<?php

namespace App\Http\Controllers\Admin;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use DB;
use Storage;
use Illuminate\Support\Facades\Schema;

class StandardController extends Controller
{
    private $syncDir = "syncStd";
    //检验标准 展示
    public function index(Request $request)
    {
        if ($request->expectsJson()) {
            $data = DB::table('a_standard')->orderBy('id','desc')->get();
            $jsonData['data'] = $data;
            return response()->json($jsonData);
        } else {
            return view('admin.standard.index');
        }
    }

    //检验标准 添加
    public function add(Request $request)
    {
        if ($request->isMethod('POST')) {
            $post_data = $request->only(['name', 'num']);
            try {
                //插入数据    insert 返回true 或 false
                $result = DB::table('a_standard')->insert($post_data);
            } catch (\Throwable $e) {
                return '2';
            }
            //由于框架自身不支持响应bool值，所以转化一种形式
            return $result ? '1' : '0';
        } else {
            return view('admin.standard.add');
        }
    }

    //检验标准 修改
    public function edit(Request $request)
    {
        $id = $request->input('id');

        if ($request->isMethod('POST')) {
            $data = $request->only(['ishide']);

            try {
                //update 返回受影响的行数
                $result = DB::table('a_standard')->where('id', $id)->update($data);
            } catch (\Throwable $e) {
                return '2';
            }

            //由于框架自身不支持响应bool值，所以转化一种形式
            return $result >= 0 ? '1' : '0';
        } else {
            //查询信息
            $info_standard = DB::table('a_standard')->find($id);

            return view('admin.standard.edit', compact('info_standard'));
        }
    }

    //检验标准 删除
    public function del(Request $request)
    {
        $id = $request->input('id');
        if (DB::table('a_std_tool_rel')->where('std_id',$id)->exists()) {
            return '2';
        }
        try {
            // delete 返回受影响的行数
            $result = DB::table('a_standard')->where('id', $id)->delete();
        } catch (\Throwable $e) {
            return '2'.$e->getMessage();
        }
        //由于框架自身不支持响应bool值，所以转化一种形式
        return $result >= 0 ? '1' : '0';
    }

    public function syncDataHb(){
        set_time_limit(0);
        ini_set('max_execution_time', 0);
        ini_set('memory_limit', '-1');
        // $std_num = 'DL/T 1476-2023';
        $std_num = request('std_num');
        if (!$std_num) {
            return '请指定标准代号';
        }
        if(config('constant.app_name') == 'HuiBangJianCe'){
            return $this->saveSyncData($std_num);
        }
        return $this->setSyncData($std_num); //同步数据库和模版
    }

    private function setSyncData($std_num){
        if(!config('constant.is_lan')){
            $this->getSyncDir(); //获取同步目录并放到当前网站目录下
        }
        $disk = Storage::disk('public');
        $std_num_file = str_replace([' ','/'],'',$std_num);
        // dd($std_num_file);
        if(!$disk->exists("{$this->syncDir}/{$std_num_file}.json")){
            return '汇邦检测中心未同步该标准！';
        }
        $data = json_decode($disk->get("{$this->syncDir}/{$std_num_file}.json"),true);
        $std_id = 0;
        $std_tool_rel_id_map = $tool_id_map = $excel_pos_id_map = $std_tool_item_rel_id_map = $item_id_map = $vol_class_id_map = $condition_key_id_map = $condition_id_map = $testdata_key_id_map = [];
        
        //$xxx_id_map 的key(或$id)是汇邦表id，value(或$id2)是当前系统表id
        try{
            foreach ($data as $table => $item) {
                switch ($table) {
                    case 'a_tool':
                        $tool2 = DB::table('a_tool')->pluck('id','name')->toArray();
                        foreach ($item as $tool_id => $item2) {
                             if (!isset($tool2[$item2['name']])) {
                                $id = $item2['id'];
                                unset($item2['id'],$item2['ctime'],$item2['ddzy_name']);
                                $id2 = DB::table('a_tool')->insertGetId($item2);
                                $tool_id_map[$id] = $id2;
                                // return $item[$tool_id]['name'].'样品类型不存在！';
                            }else{
                                $tool_id_map[$tool_id] = $tool2[$item2['name']];
                            }
                        }
                        break;
                    case 'a_testitem':
                        if (!Schema::hasColumn('a_testitem', 'id_map')) {
                            DB::statement("alter table a_testitem add column `id_map` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '试验数据上传对照项目id'");
                        }
                        $testitem2 = DB::table('a_testitem')->pluck('id','name')->toArray();
                        // dd($item);
                        $inserts = [];
                        foreach ($item as $item_id => $item2) {
                             if (!isset($testitem2[$item2['name']])) {
                                unset($item2['ctime'],$item2['ddzy_name'],$item2['id_map']);
                                //先插入没有id的数据，将有id的重新赋值id插入
                                if (!in_array($item_id, $testitem2)) {
                                    // dd($item2);
                                    $id2 = DB::table('a_testitem')->insertGetId($item2);
                                    $item_id_map[$item_id] = $id2;
                                }else{
                                    $inserts[$item_id] = $item2;
                                }
                                // return $item[$item_id]['name'].'项目不存在！'.$item_id;
                            }else{
                                $item_id_map[$item_id] = $testitem2[$item2['name']];
                            }
                        }
                        // dd($inserts);
                        $maxId = DB::table('a_testitem')->max('id');
                        foreach($inserts as $item_id=>$insert){
                            $maxId += 1;
                            $insert['id'] = $maxId;
                            $id2 = DB::table('a_testitem')->insertGetId($insert);
                            $item_id_map[$item_id] = $id2;
                        }
                        //因为电学试验不能加项目id，这里修改项目映射id_map
                        foreach ($item as $item_id => $item2) {
                            if($item2['id_map']){
                                DB::table('a_testitem')->where('id',$item_id_map[$item_id])->update([
                                    'id_map'=>$item_id_map[$item2['id_map']]
                                ]);
                            }
                        }
                        // dd($item_id_map);
                        break;
                    case 'a_standard':
                        // dd($std_num);
                        $std_id = DB::table($table)->where('num',$std_num)->value('id');
                        $files = $disk->files("{$this->syncDir}/".$item['id']);
                        if (!$std_id) {
                            unset($item['id']);
                            $std_id = DB::table($table)->insertGetId($item);
                        }
                        //将该标准下的所有项目先隐藏，后面对照项目对照到的再打开
                        DB::table('a_std_tool_item_rel')->where(['std_id'=>$std_id])->update(['ishide'=>1]);
                        foreach ($files as $file) {
                            // dd($std_id);
                            $file2 = 'ExcelTemplate/'.$std_id.'/'.ltrim($file,"{$this->syncDir}/{$item['id']}/");
                            if(!$disk->exists($file2)){
                                $disk->copy($file,$file2);
                            }
                        }
                        // dd($files);
                        break;
                    case 'a_std_tool_rel':
                        foreach ($item as $item2) {
                            $id = $item2['id'];
                            unset($item2['id'], $item2['ctime']);
                            $item2['std_id'] = $std_id;
                            $tool_id2 = $tool_id_map[$item2['tool_id']];
                            $item2['tool_id'] = $tool_id2;
                            $info = DB::table($table)->where(['std_id'=>$std_id,'tool_id'=>$tool_id2])->first();
                            if(!$info){
                                $id2 = DB::table($table)->insertGetId($item2);
                                $std_tool_rel_id_map[$id] = $id2;
                            }else{
                                $std_tool_rel_id_map[$id] = $info->id;
                            }
                        }
                        break;
                    case 'a_excel_pos':
                        foreach ($item as $std_tool_rel_id => $item3) {
                            foreach ($item3 as $item2) {
                                $id = $item2['id'];
                                unset($item2['id']);
                                $std_tool_rel_id2 = $std_tool_rel_id_map[$std_tool_rel_id];
                                $item2['std_tool_rel_id'] = $std_tool_rel_id2;
                                $info = DB::table($table)->where(['std_tool_rel_id'=>$std_tool_rel_id2,'name'=>$item2['name']])->first();
                                if(!$info){
                                    $id2 = DB::table($table)->insertGetId($item2);
                                    $excel_pos_id_map[$id] = $id2;
                                }else{
                                    if(!$info->line_num){
                                        DB::table($table)->where('id',$info->id)->update($item2);
                                    }
                                    $excel_pos_id_map[$id] = $info->id;
                                }
                            }
                        }
                        // dd($excel_pos_id_map);
                        break;
                    case 'a_std_tool_item_rel':
                        foreach ($item as $item2) {
                            // dd($item2);
                            $id = $item2['id'];
                            unset($item2['id'], $item2['ctime']);
                            $tool_id2 = $tool_id_map[$item2['tool_id']];
                            $item_id2 = $item_id_map[$item2['testitem_id']];
                            $item2['std_id'] = $std_id;
                            $item2['tool_id'] = $tool_id2;
                            $item2['testitem_id'] = $item_id2;
                            // dd($item2);
                            $info = DB::table($table)->where(['std_id'=>$std_id,'tool_id'=>$tool_id2,'testitem_id'=>$item_id2])->first();
                            if(!$info){
                                $id2 = DB::table($table)->insertGetId($item2);
                                $std_tool_item_rel_id_map[$id] = $id2;
                            }else{
                                DB::table($table)->where(['std_id'=>$std_id,'tool_id'=>$tool_id2,'testitem_id'=>$item_id2])->update(['ishide'=>0]);  //对照项目到的显示
                                $std_tool_item_rel_id_map[$id] = $info->id;
                            }
                        }
                        // dd($item);
                        break;
                    case 'a_voltage_class':
                        foreach ($item as $item2) {
                            $id = $item2['id'];
                            unset($item2['id']);
                            $tool_id2 = $tool_id_map[$item2['tool_id']];
                            $item2['std_id'] = $std_id;
                            $item2['tool_id'] = $tool_id2;
                            $item2['std_tool_rel_id'] = $std_tool_rel_id_map[$item2['std_tool_rel_id']];
                            // dd($item2);
                            $info = DB::table($table)->where(['std_id'=>$std_id,'tool_id'=>$tool_id2,'val'=>$item2['val']])->first();
                            if(!$info){
                                $id2 = DB::table($table)->insertGetId($item2);
                                $vol_class_id_map[$id] = $id2;
                            }else{
                                $vol_class_id_map[$id] = $info->id;
                            }
                        }
                        // dd($vol_class_id_map);
                        break;
                    case 'a_condition_key':
                        foreach ($item as $item3) {
                            foreach ($item3 as $key => $item2) {
                                $id = $item2['id'];
                                unset($item2['id']);
                                $tool_id = $tool_id_map[$item2['tool_id']];
                                $std_tool_item_rel_id2 = data_get($std_tool_item_rel_id_map,$item2['std_tool_item_rel_id'],0); //可能没有，没有的在检测中心隐藏了，不需要同步
                                if ($std_tool_item_rel_id2 === 0) {
                                    continue;
                                }
                                $item_id = $item_id_map[$item2['item_id']];
                                $item2['std_id'] = $std_id;
                                $item2['tool_id'] = $tool_id;
                                $item2['item_id'] = $item_id;
                                $item2['std_tool_item_rel_id'] = $std_tool_item_rel_id2;
                                // dd($item2);
                                $info = DB::table($table)->where(['std_tool_item_rel_id'=>$std_tool_item_rel_id2,'key'=>$item2['key']])->first();
                                if(!$info){
                                    $id2 = DB::table($table)->insertGetId($item2);
                                    $condition_key_id_map[$id] = $id2;
                                }else{
                                    $condition_key_id_map[$id] = $info->id;
                                }
                            }
                        }
                        break;
                    case 'a_condition':
                        foreach ($item as $condition_key_id => $item3) {
                            
                            foreach ($item3 as $item2) {
                                $id = $item2['id'];
                                unset($item2['id']);
                                $condition_key_id2 = $condition_key_id_map[$item2['condition_key_id']];
                                $item2['condition_key_id'] = $condition_key_id2;
                                $vol_class_id = $item2['vol_class_id'] == 0 ? $item2['vol_class_id'] : $vol_class_id_map[$item2['vol_class_id']];
                                $item2['vol_class_id'] = $vol_class_id;
                                // dd($item3,$item2);
                                $info = DB::table($table)->where(['condition_key_id'=>$condition_key_id2,'vol_class_id'=>$vol_class_id])->first();
                                if(!$info){
                                    $id2 = DB::table($table)->insertGetId($item2);
                                    // $condition_id_map[$id] = $id2;
                                }else{
                                    // DB::table($table)->where(['condition_key_id'=>$condition_key_id2,'vol_class_id'=>$vol_class_id])->update(['val'=>$item2['val']]);
                                    // $condition_id_map[$id] = $info->id;
                                }
                            }
                        }
                        // dd($condition_id_map);
                        break;
                    case 'a_testdata_key':
                        foreach ($item as $item2) {
                            $id = $item2['id'];
                            unset($item2['id']);
                            $tool_id = $tool_id_map[$item2['tool_id']];
                            $item_id = $item_id_map[$item2['item_id']];
                            $std_tool_item_rel_id2 = data_get($std_tool_item_rel_id_map,$item2['std_tool_item_rel_id'],0); //可能没有，没有的在检测中心隐藏了，不需要同步
                            if ($std_tool_item_rel_id2 === 0) {
                                continue;
                            }
                            $item2['std_id'] = $std_id;
                            $item2['tool_id'] = $tool_id;
                            $item2['item_id'] = $item_id;
                            $item2['std_tool_item_rel_id'] = $std_tool_item_rel_id2;
                            // dd($item,$item2);
                            $info = DB::table($table)->where(['std_tool_item_rel_id'=>$std_tool_item_rel_id2,'data_key'=>$item2['data_key']])->first();
                            if(!$info){
                                $id2 = DB::table($table)->insertGetId($item2);
                                $testdata_key_id_map[$id] = $id2;
                            }else{
                                $testdata_key_id_map[$id] = $info->id;
                            }
                        }
                        break;
                    default:
                        // code...
                        break;
                }
            }
            DB::commit();
        }catch(\Exception $exception){
            DB::rollBack();
            $errCode = $exception->getCode();
            if ($errCode == 2002) {
                return '数据库连接错误！';
            }
            return $exception->getMessage().'，errcode:'.$errCode.'，errline:'.$exception->getLine();
        }
        if(!config('constant.is_lan')){
            $disk->deleteDirectory($this->syncDir);
        }
        return '同步成功！';
    }

    private function getSyncDir(){
        $disk = Storage::disk('public');
        $sync2dir = $disk->path($this->syncDir);    
        $sync_from_dir = '/www/wwwroot/huibangjiance.com/storage/app/public/'.$this->syncDir;
        $files = scandir($sync_from_dir);
        foreach ($files as $file) {
            $sync_from_file = $sync_from_dir.'/'.$file;
            if($file != '.' && $file != '..'){
                if (is_file($sync_from_file)) {
                    $disk->put($this->syncDir.'/'.$file,file_get_contents($sync_from_file));
                }else{
                    foreach (scandir($sync_from_file) as $file2) {
                        if($file2 != '.' && $file2 != '..'){
                            $sync_from_file2 = $sync_from_file.'/'.$file2;
                            $disk->put($this->syncDir.'/'.$file.'/'.$file2,file_get_contents($sync_from_file2));
                        }
                    }
                }
            }
        }        
    }
    private function saveSyncData($std_num){
        $disk = Storage::disk('public');
        $tool = DB::table('a_tool')->get()->keyBy('id')->toArray();
        $testitem = DB::table('a_testitem')->get()->keyBy('id')->toArray();
        $std = DB::table('a_standard')->where('num',$std_num)->first();
        //////////关联标准 start///////////////
        $std_tool_rel = DB::table('a_std_tool_rel')->where('std_id',$std->id)->get()->toArray();
        //////////关联标准 end///////////////
        ////////////////报告模板 start////////////////////
            ////////////////excel_pos start////////////////////
                $excel_pos = [];
                foreach ($std_tool_rel as $item) {
                    $excel_pos[$item->id] = DB::table('a_excel_pos')->where('std_tool_rel_id',$item->id)->get()->toArray();
                }
            ////////////////excel_pos end////////////////////
            ////////////////复制模版文件 start////////////////////
                $files = $disk->allFiles('ExcelTemplate/'.$std->id);
                $disk->deleteDirectory($this->syncDir.'/'.$std->id);
                foreach ($files as $file) {
                    $disk->copy($file, $this->syncDir.'/'.ltrim($file,'ExcelTemplate/'));
                }
            ////////////////复制模版文件 end////////////////////
        ////////////////报告模板 end////////////////////
        ////////////////关联参数 start////////////////////
            $vol_class = DB::table('a_voltage_class')->where('std_id',$std->id)->get()->toArray();
        ////////////////关联参数 end////////////////////
        ////////////////关联项目 start////////////////////
            $std_tool_item_rel = DB::table('a_std_tool_item_rel')->where('std_id',$std->id)->where('ishide',0)->get()->toArray();
        ////////////////关联项目 end////////////////////

        ////////////////试验条件 start////////////////////
            $condition_key = $condition = [];
            foreach ($std_tool_item_rel as $item) {
                $condition_key[$item->id] = $keys = DB::table('a_condition_key')->where('std_tool_item_rel_id',$item->id)->get()->toArray();
                ///////关联值 start////////////////
                foreach ($keys as $key) {
                    $condition[$key->id] = DB::table('a_condition')->where('condition_key_id',$key->id)->get()->toArray();
                }
                ///////关联值 end////////////////
            }
        ////////////////试验条件 end////////////////////
        ////////////////试验数据 start////////////////////
            $testdata_key = DB::table('a_testdata_key')->where('std_id',$std->id)->get()->toArray();
        ////////////////试验数据 end////////////////////
        
        $excel_pos_std_tool_item_rel = [];
        foreach ($std_tool_item_rel as $item) {
            $excel_pos_std_tool_item_rel[$item->id] = DB::table('a_excel_pos_std_tool_item_rel')->where('std_tool_item_rel_id',$item->id)->get()->toArray();
        }
        $data = [
            'a_tool'=>$tool,
            'a_testitem'=>$testitem,
            'a_standard'=>$std,
            'a_std_tool_rel'=>$std_tool_rel,
            'a_excel_pos'=>$excel_pos,
            'a_std_tool_item_rel'=>$std_tool_item_rel,
            'a_voltage_class'=>$vol_class,
            'a_condition_key'=>$condition_key,
            'a_condition'=>$condition,
            'a_testdata_key'=>$testdata_key,
        ];
        $data = json_encode($data,JSON_UNESCAPED_UNICODE);
        $std_num_file = str_replace([' ','/'],'',$std_num);
        $disk->put($this->syncDir."/{$std_num_file}.json",$data);
        return '数据同步到'.$this->syncDir.'目录了！';
    }
}
